package pl.enigmatic.time;

public abstract class TimeCounterLong {

	/** last measured time tick */
	protected long firstTick;
	/** last measured time tick */
	protected long lastTick;

	protected TimeCounterLong() {
		restart();
	}

	protected abstract long tick();

	/**
	 * Restarts <code>this</code> time counter - sets the first and last measured time tick to the current time.
	 * @return the new tick value
	 */
	public long restart() {
		return firstTick = lastTick = tick();
	}

	/**
	 * @return the starting tick measured
	 */
	public long getFirstTick() {
		return firstTick;
	}

	/**
	 * @return the last measured time tick
	 */
	public long getLastTick() {
		return lastTick;
	}

	/**
	 * @return the difference between <code>now</code> and the first measured tick
	 */
	public long getElapsedTime(long now) {
		return now - firstTick;
	}

	/**
	 * @return the difference between the last measured tick and the first measured tick
	 */
	public long getMeasuredTime() {
		return getElapsedTime(lastTick);
	}

	/**
	 * @return the difference between now and the first measured tick
	 */
	public long getElapsedTime() {
		return getElapsedTime(tick());
	}

	/**
	 * Returns the time elapsed between last measured time tick and the given <code>now</code> time value. Also sets the last tick time value to the
	 * given <code>now</code> time.
	 * @param now the <code>long</code> value representing the <i>current</i> moment
	 * @return time elapsed between last measured tick and <code>now</code>
	 */
	public long getDelta(long now) {
		final long res = now - lastTick;
		lastTick = now;
		return res;
	}

	/**
	 * Does the same as {@link TimeCounterMilli#getDelta(long)} where the passed value would be the real <i>now</i> time.
	 * @return time elapsed between last measured tick and now
	 */
	public long getDelta() {
		return getDelta(tick());
	}

}